package cn.wildfire.chat.kit.conversationlist;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;

import com.sourcemuch.im.caiba.CaiBaChatApp;
import com.sourcemuch.im.caiba.ManumotiveIBinder;
import com.sourcemuch.im.caiba.R;import com.sourcemuch.im.caiba.R2;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import cn.wildfire.chat.app.extendsion.widgets.DispenseRecyclerView;
import cn.wildfire.chat.kit.WfcUIKit;
import cn.wildfire.chat.kit.conversationlist.notification.ConnectionStatusNotification;
import cn.wildfire.chat.kit.conversationlist.notification.StatusNotificationViewModel;
import cn.wildfire.chat.kit.conversationlist.viewholder.ConversationViewHolder;
import cn.wildfire.chat.kit.user.UserViewModel;
import cn.wildfirechat.client.ConnectionStatus;
import cn.wildfirechat.model.Conversation;
import cn.wildfirechat.model.ConversationInfo;
import cn.wildfirechat.model.GroupMember;
import cn.wildfirechat.model.UserInfo;
import cn.wildfirechat.remote.ChatManager;

/**
 * Create by HEKE, 2019/9/7 11:56
 * TODO 群聊列表(消息)
 */
public class ConversationGroupListFragment extends Fragment {

    private DispenseRecyclerView recyclerView;
    private ConversationListAdapter adapter;
    private static final List<Conversation.ConversationType> types = Arrays.asList(Conversation.ConversationType.Group);
    private static final List<Integer> lines = Arrays.asList(0);

    private ConversationGroupListViewModel conversationGroupListViewModel;
    private UserViewModel userViewModel;
    private Observer<ConversationInfo> conversationInfoObserver = new Observer<ConversationInfo>() {
        @Override
        public void onChanged(@Nullable ConversationInfo conversationInfo) {
            // just handle what we care about
            if (types.contains(conversationInfo.conversation.type) && lines.contains(conversationInfo.conversation.line)) {
                adapter.submitConversationInfo(conversationInfo);
                // scroll or not?
                // recyclerView.scrollToPosition(0);
            }
        }
    };

    private Observer<Conversation> conversationRemovedObserver = new Observer<Conversation>() {
        @Override
        public void onChanged(@Nullable Conversation conversation) {
            if (conversation == null) {
                return;
            }
            if (types.contains(conversation.type) && lines.contains(conversation.line)) {
                adapter.removeConversation(conversation);
            }
        }
    };

    // 会话同步
    private Observer<Object> settingUpdateObserver = o -> reloadConversations();

    private Observer<List<UserInfo>> userInfoLiveDataObserver = (userInfos) -> {
        adapter.updateUserInfos(userInfos);
    };

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.conversationlist_frament, container, false);
        recyclerView = view.findViewById(R.id.recyclerView);
        recyclerView.setOnDispenseTouchSelectListener(onDispenseTouchSelectListener);
        init();
        return view;
    }

    public RecyclerView getRecyclerView() {
        return recyclerView;
    }

    public ConversationListAdapter getAdapter() {
        return adapter;
    }

    /**
     * 滑动栏操作点击回调事件
     */
    protected DispenseRecyclerView.OnDispenseTouchSelectListener onDispenseTouchSelectListener = new DispenseRecyclerView.OnDispenseTouchSelectListener() {
        @Override
        public void clieckSlide(View view, int position) {
            try {
                ConversationViewHolder conversationViewHolder = (ConversationViewHolder) view.getTag();
                if (conversationViewHolder != null) {
                    if (position == 0) {
                        // 置顶/取消置顶操作
                        conversationViewHolder.setConversationTop(!conversationViewHolder.isConversationTopShow());
                    } else {
                        // 删除操作
                        conversationViewHolder.removeConversation();
                    }
                }
            } catch (ClassCastException e) {
                e.printStackTrace();
            }
        }

        @Override
        public boolean isItemViewAllowSlide(View view) {
            return true;
        }

        @Override
        public void checkClickChildView(View clickView, View rootView, int id) {
        }

    };

    /**
     * 过滤无效的群组会话信息
     * @param conversationInfos
     * @return
     * */
    private List<ConversationInfo> filterConversationList(List<ConversationInfo> conversationInfos){
        List<ConversationInfo> conversationInfoList = new ArrayList<>();
        try {
            // 过滤无效会话
            if (conversationInfos != null && conversationInfos.size() > 0) {
                for (ConversationInfo conversationInfo : conversationInfos) {
                    GroupMember groupMember = ChatManager.Instance().getGroupMember(conversationInfo.conversation.target, userViewModel.getUserId());
                    if (groupMember != null && groupMember.type != GroupMember.GroupMemberType.Removed) {
                        conversationInfoList.add(conversationInfo);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conversationInfoList;
    }

    /**
     * modify by HEKE , 2019/8/22 12:27
     * TODO 调用刷新会话窗口内容
     */
    public void refreshConversations() {
        try {
            conversationGroupListViewModel = ViewModelProviders
                    .of(getActivity(), new ConversationListViewModelFactory(types, lines))
                    .get(ConversationGroupListViewModel.class);
            // 会话数据列表数据通过观察者模式刷新数据
            conversationGroupListViewModel.getConversationListAsync(types, lines)
                    .observe(this, conversationInfos -> {
                        List<ConversationInfo> conversationInfoList = filterConversationList(conversationInfos);
                        adapter.setConversationInfos(conversationInfoList);
                        adapter.notifyDataSetChanged();
                        adapter.setSelectedConversationViewHolder(null);
                    });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * modify by HEKE , 2019/8/28 14:44 TODO 刷新显示
     */
    public void refreshNotify() {
        try {
            conversationGroupListViewModel.conversationInfoLiveData().observeForever(conversationInfoObserver);
            conversationGroupListViewModel.conversationRemovedLiveData().observeForever(conversationRemovedObserver);
            conversationGroupListViewModel.settingUpdateLiveData().observeForever(settingUpdateObserver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void init() {
        try {
            ManumotiveIBinder manumotiveIBinder = ((CaiBaChatApp) getContext().getApplicationContext()).manumotiveIBinder;
            if (adapter == null) {
                adapter = new ConversationListAdapter(this);
            }
            adapter.setSelectedConversationViewHolder(null);
            if (manumotiveIBinder != null) {
                conversationGroupListViewModel = (ConversationGroupListViewModel) manumotiveIBinder.getObject(ManumotiveIBinder.GROUP_LIST_VIEWMODEL);
            } else {
                conversationGroupListViewModel = ViewModelProviders
                        .of(getActivity(), new ConversationListViewModelFactory(types, lines))
                        .get(ConversationGroupListViewModel.class);
            }
            // 会话数据列表数据通过观察者模式刷新数据
            conversationGroupListViewModel.getConversationListAsync(types, lines)
                    .observe(this, conversationInfos -> {
                        List<ConversationInfo> conversationInfoList = filterConversationList(conversationInfos);
                        adapter.setConversationInfos(conversationInfoList);
                        adapter.notifyDataSetChanged();
                        adapter.setSelectedConversationViewHolder(null);
                    });
            recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

            // 定义子项背景色
            DividerItemDecoration itemDecor = new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL);
            itemDecor.setDrawable(ContextCompat.getDrawable(getContext(), R.drawable.recyclerview_horizontal_divider));
            recyclerView.addItemDecoration(itemDecor);
            recyclerView.setAdapter(adapter);
            ((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);

            conversationGroupListViewModel.conversationInfoLiveData().observeForever(conversationInfoObserver);
            conversationGroupListViewModel.conversationRemovedLiveData().observeForever(conversationRemovedObserver);
            conversationGroupListViewModel.settingUpdateLiveData().observeForever(settingUpdateObserver);

            userViewModel = WfcUIKit.getAppScopeViewModel(UserViewModel.class);
            userViewModel.userInfoLiveData().observeForever(userInfoLiveDataObserver);

            StatusNotificationViewModel statusNotificationViewModel = WfcUIKit.getAppScopeViewModel(StatusNotificationViewModel.class);
            statusNotificationViewModel.statusNotificationLiveData().observe(this, new Observer<Object>() {
                @Override
                public void onChanged(Object o) {
                    adapter.updateStatusNotification(statusNotificationViewModel.getNotificationItems());
                }
            });
            conversationGroupListViewModel.connectionStatusLiveData().observe(this, status -> {
                ConnectionStatusNotification connectionStatusNotification = new ConnectionStatusNotification();
                switch (status) {
                    case ConnectionStatus.ConnectionStatusConnecting:
                        connectionStatusNotification.setValue("正在连接...");
                        statusNotificationViewModel.showStatusNotification(connectionStatusNotification);
                        break;
                    case ConnectionStatus.ConnectionStatusConnected:
                        statusNotificationViewModel.removeStatusNotification(connectionStatusNotification);
                        break;
                    case ConnectionStatus.ConnectionStatusUnconnected:
                        connectionStatusNotification.setValue("连接失败");
                        statusNotificationViewModel.showStatusNotification(connectionStatusNotification);
                        break;
                    default:
                        break;
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void reloadConversations() {
        conversationGroupListViewModel.getConversationListAsync(types, lines)
                .observe(this, conversationInfos -> {
                    List<ConversationInfo> conversationInfoList = filterConversationList(conversationInfos);
                    adapter.setConversationInfos(conversationInfoList);
                    adapter.notifyDataSetChanged();
                });
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        try {
            conversationGroupListViewModel.conversationInfoLiveData().removeObserver(conversationInfoObserver);
            conversationGroupListViewModel.conversationRemovedLiveData().removeObserver(conversationRemovedObserver);
            conversationGroupListViewModel.settingUpdateLiveData().removeObserver(settingUpdateObserver);
            userViewModel.userInfoLiveData().removeObserver(userInfoLiveDataObserver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
